/**
  ******************************************************************************
  * @file    g_bt.h
  * @author  Yichip
  * @version V1.0
  * @date    2021/1/20
  * @brief   Yichip bluetooth encapsulation.The HCI protocol refers to YC Dual mode module spec-v4.15
*
  ******************************************************************************
  */

#ifndef __G_BT_H__
#define __G_BT_H__

#include "g_1903.h"
#include "g_gpio.h"
#include "board_config.h"
#include "bt_code.h"
#include "g_timer.h"

#define UART_EXT_ENABLE    0

#if     UART_EXT_ENABLE
#define HCI_TPYE_HEADER     4
#else
#define HCI_TPYE_HEADER     3
#endif


/* Private define ------------------------------------------------------------*/

//#define debug_patch
//#define BT_ERROR_LOG
//#define BT_LOG

#define BT_VERSION          EVB_3160AB_BOARD
#define GETWORD(p)    ((uint16_t)((*(volatile uint8_t *)((uint32_t)p)) |((((uint16_t)(*(volatile uint8_t *)((uint32_t)(p+1))))<<8) & 0xff00)))

#define HCI_CMD                           0x01
#define HCI_EVENT                         0x02
#define MAX_BLUETOOTH_DATA_LEN            255

/*CMD*/
#define HCI_CMD_SET_BT_ADDR               0x00  //设置 BT3.0 地址
#define HCI_CMD_SET_BLE_ADDR              0x01  //设置 BLE 地址
#define HCI_CMD_SET_VISIBILITY            0x02  //设置可发现和广播
#define HCI_CMD_SET_BT_NAME               0x03  //设置 BT3.0 名称
#define HCI_CMD_SET_BLE_NAME              0x04  //设置 BLE 名称
#define HCI_CMD_SEND_SPP_DATA             0x05  //发送 BT3.0（SPP）数据
#define HCI_CMD_SEND_BLE_DATA             0x09  //发送 BLE 数据
#define HCI_CMD_STATUS_REQUEST            0x0B  //请求蓝牙状态
#define HCI_CMD_SET_PAIRING_MODE          0x0C  //设置配对模式
#define HCI_CMD_SET_PINCODE               0x0D  //设置配对码
#define HCI_CMD_SET_UART_FLOW             0x0E  //设置UART流控
#define HCI_CMD_SET_UART_BAUD             0x0F  //设置UART波特率
#define HCI_CMD_VERSION_REQUEST           0x10  //查询模块固件版本
#define HCI_CMD_BT_DISCONNECT             0x11  //断开 BT3.0 连接
#define HCI_CMD_BLE_DISCONNECT            0x12  //断开 BLE 连接
#define HCI_CMD_SET_COD                   0x15  //设置 COD
#define HCI_CMD_SET_NVRAM                 0x26  //下发 NV 数据
#define HCI_CMD_ENTER_SLEEP_MODE          0x27  //进入睡眠模式
#define HCI_CMD_CONFIRM_GKEY              0x28  //Numeric Comparison 配对方式中对密钥的比较（见HCI_EVENT_GKEY注释）
#define HCI_CMD_GET_CREADIT_GIVEN         0x29  //用于设置spp流控(并非开启)
#define HCI_CMD_AUTO_ADV_SCAN             0x2A  //用于设置BLE ADV DATA
#define HCI_CMD_POWER_REQ                 0x2B  //用于查询模块电源电压
#define HCI_CMD_POWER_SET                 0x2C  //用于设置模块读取电源电压功能开关
#define HCI_CMD_PASSKEY_ENTRY             0x30  //passkey配对方式中对密钥的比较
#define HCI_CMD_SET_GPIO                  0x31  //用于设置GPIO，但并不是每个GPIO都可设（见HCI_CMD_SET_GPIO注释）
#define HCI_CMD_READ_GPIO                 0x32  //用于读取 GPIO 设置
#define HCI_CMD_LE_SET_PAIRING            0x33  //设置 BLE 配对模式
#define HCI_CMD_LE_SET_ADV_DATA           0x34  //用于设置 BLE ADV DATA
#define HCI_CMD_LE_SET_SCAN_DATA          0x35  //用于设置 Scan Data
#define HCI_CMD_LE_SEND_CONN_UPDATE_REQ   0x36  //用于设置 CONNECTION PARAMETER UPDATE REQUEST 数据并发送
#define HCI_CMD_LE_SET_ADV_PARM           0x37  //用于设置 ADVR 的间隔和持续的时间
#define HCI_CMD_LE_START_PAIRING          0x38  //用于开始配对
#define HCI_CMD_SET_GPIO_WAKEUP           0x40  //用于在发送 UART 数据前唤醒上位机的 GPIO 设置
#define HCI_CMD_SET_TX_POWER              0x42  //用于设置发射功率
#define HCI_CMD_LE_CONFIRM_GKEY           0x48  //用于 Numeric Comparison 配对方式中对密钥的比较
#define HCI_CMD_REJECT_JUSTWORK           0x49  //用于设置拒绝Justwork配对方式
#define HCI_CMD_RESET_CHIP_REQ            0x51  //用于复位芯片
#define HCI_CMD_LE_SET_FIXED_PASSKEY      0x61  //用于设置Passkey
#define HCI_CMD_DELETE_CUSTOMIZE_SERVICE  0x76  //用于删除非系统服务及特征
#define HCI_CMD_ADD_SERVICE_UUID          0x77  //用于新增自定义服务
#define HCI_CMD_ADD_CHARACTERISTIC_UUID   0x78  //用于新增特征
#define HCI_CMD_PASSKEY_ENTRY_INPUT       0x7A  //用于输入Passkey
#define HCI_CMD_CONNECT_BNEP              0x7E  //建立BNEP连接
#define HCI_CMD_CONNECT_TCP               0x7F  //建立TCP连接
#define HCI_CMD_DISCONNECT_TCP            0x80  //断开TCP连接
#define HCI_CMD_BNEP_SEND_TCP_DATA        0x81  //发送TCP数据
#define HCI_CMD_DNS_REQ                   0x82  //域名解析指令
#define HCI_CMD_SEND_UDP_DATA             0x84  //发送UDP数据
#define HCI_CMD_SEND_BIG_DATA             0x85  //发送TCP大包数据
#define HCI_CMD_BLE_SET_PHY               0x90  //用于修改BLE的PHY
#define HCI_CMD_BLE_READ_CURRENT_PHY      0x91  //用于查询BLE的PHY
#define HCI_CMD_BLE_SET_DLE               0x92  //用于设置BLE的DLE功能
#define HCI_CMD_READ_CHIP_DATA            0x93  //用于读取内存的值，操作码为0x93
#define HCI_CMD_WRITE_CHIP_DATA           0x94  //用于写内存的值，操作码为0x94
#define HCI_CMD_WECHAT_SEND_DATA          0x95  //用于发送微信协议的数据，操作码为0x95。
#define HCI_CMD_SET_LPM_MODE              0xFF  //开关低功耗

/*EVENT*/
#define HCI_EVENT_BT_CONNECTED            0x00  /**BT3.0 连接建立*/
#define HCI_EVENT_BLE_CONNECTED           0x02  /**BLE 连接建立*/
#define HCI_EVENT_BT_DISCONNECTED         0x03  /**BT3.0 连接断开*/
#define HCI_EVENT_BLE_DISCONNECTED        0x05  /**BLE 连接断开*/
#define HCI_EVENT_CMD_COMPLETE            0x06  /**命令已完成*/
#define HCI_EVENT_SPP_DATA_RECEIVED       0x07  /**接收到 BT3.0 数据（SPP）*/
#define HCI_EVENT_BLE_DATA_RECEIVED       0x08  /**接收到 BLE 数据*/
#define HCI_EVENT_I_AM_READY              0x09  /**模块准备好*/
#define HCI_EVENT_STAUS_RESPONSE          0x0A  /**状态回复*/
#define HCI_EVENT_NVRAM_CHANGED           0x0D  /**上传 NVRAM 数据*/
#define HCI_EVENT_GKEY                    0x0E  /**比较密钥回复事件*/
#define HCI_EVENT_UART_EXCEPTION          0x0F  /**HCI包格式错误*/
#define HCI_EVENT_GET_PASSKEY             0x10  /**PASSKEY 配对方式中通知MCU 返回密钥,MCU收到此事件后需发送HCI_CMD_PASSKEY_ENTRY指令回复蓝牙模块*/
#define HCI_EVENT_PAIRING_COMPLETED       0x11  /**配对完成的事件，通知 MCU配对完成*/
#define HCI_EVENT_LE_PAIRING_STATE        0x14  /**上报配对状态*/
#define HCI_EVENT_LE_ENCRYPTION_STATE     0x15  /**上报加密状态事件*/
#define HCI_EVENT_LE_GKEY                 0x1D  /**比较密钥回复事件*/
#define HCI_EVENT_UUID_HANDLE             0x29  /**模块收到设置UUID相关的CMD会回复此事件*/
#define HCI_EVENT_LE_INPUT_GKEY           0x2b  /**在蓝牙发起配对的时候使用passkey，模块会向MCU发送事件*/
#define HCI_EVENT_BNEP_CONNECT            0x2c  /**通知MCU BNEP连接成功*/
#define HCI_EVENT_BNEP_DISCONNECT         0x2d  /**通知MCU BNEP断开连接*/
#define HCI_EVENT_BNEP_CONNECT_FAIL       0x2e  /**通知MCU BNEP连接失败原因*/
#define HCI_EVENT_TCP_CONNECT             0x2f  /**通知MCU TCP连接成功*/
#define HCI_EVENT_TCP_DISCONNECT          0x30  /**通知MCU TCP断开连接*/
#define HCI_EVENT_BNEP_RECEIVE_TCP_DATA   0x31  /*接收到TCP数据*/
#define HCI_EVNET_TCP_FAIL                0x32  /*TCP连接或者断开失败*/
#define HCI_EVENT_TCP_CONNECT_LOG         0x33  /*TCP连接LOG*/
#define HCI_EVENT_BNEP_CHIP_ERROR         0x34  /*芯片不支持BNEP*/
#define HCI_EVENT_DNS_RSP                 0x35  /*DNS返回的ip地址*/
#define HCI_EVENT_BB_DISCONNECT           0x36  /*经典蓝牙baseband断开后返回的事件*/
#define HCI_EVENT_BT_NAME                 0x37  /*BT master name*/
#define HCI_EVENT_UDP_INFO                0x38  /*UDP信息头,包含远端IP、本地IP、远端端口、本地端口,后面会紧随一包UDP数据*/
#define HCI_EVENT_BNEP_RECEIVE_UDP_DATA   0x39  /*接收到UDP数据*/
#define HCI_EVENT_BIG_DATA_FINISH         0x3a  /*大数据分包发送完成事件*/
#define HCI_EVENT_BIG_DATA_STATUS         0x3b  /*大数据分包发送状态*/
#define HCI_BLE_UPDATE_PHY_EVENT          0x40  /**在蓝牙请求当前PHY时，模块会向MCU发送事件*/
#define HCI_BLE_WECHAT_RECEIVE_PUSH_DATA  0x41  /**在蓝牙收到BLE微信协议数据时，模块会向MCU发送事件*/
/* Private typedef -----------------------------------------------------------*/

/**
  * @brief  event code enum definition
  */
typedef enum
{
    BT_CONNECTED                = HCI_EVENT_BT_CONNECTED,
    BLE_CONNECTED               = HCI_EVENT_BLE_CONNECTED,
    BT_DISCONNECTED             = HCI_EVENT_BT_DISCONNECTED,
    BLE_DISCONNECTED            = HCI_EVENT_BLE_DISCONNECTED,
    BT_DATA                     = HCI_EVENT_SPP_DATA_RECEIVED,
    BLE_DATA                    = HCI_EVENT_BLE_DATA_RECEIVED,
    NVRAM_DATA                  = HCI_EVENT_NVRAM_CHANGED,
    CONFIRM_GKEY                = HCI_EVENT_GKEY,
    PASSKEY                     = HCI_EVENT_GET_PASSKEY,
    PAIRING_COMPLETED           = HCI_EVENT_PAIRING_COMPLETED,
    PAIRING_STATE               = HCI_EVENT_LE_PAIRING_STATE,
    BNEP_CONNECT                = HCI_EVENT_BNEP_CONNECT,
    TCP_CONNECT                 = HCI_EVENT_TCP_CONNECT,
    BNEP_RECEIVE_TCP_DATA       = HCI_EVENT_BNEP_RECEIVE_TCP_DATA,
    TCP_DISCONNECT              = HCI_EVENT_TCP_DISCONNECT,
    BNEP_DISCONNECT             = HCI_EVENT_BNEP_DISCONNECT,
    BNEP_CONNECT_FAIL           = HCI_EVENT_BNEP_CONNECT_FAIL,
    TCP_FAIL                    = HCI_EVNET_TCP_FAIL,
    TCP_CONNECT_LOG             = HCI_EVENT_TCP_CONNECT_LOG,
    BNEP_CHIP_ERROR             = HCI_EVENT_BNEP_CHIP_ERROR,
    DNS_RSP                     = HCI_EVENT_DNS_RSP,
    BB_DISCONNECT               = HCI_EVENT_BB_DISCONNECT,
    BT_NAME                     = HCI_EVENT_BT_NAME,
    UDP_INFO                    = HCI_EVENT_UDP_INFO,
    BNEP_RECEIVE_UDP_DATA       = HCI_EVENT_BNEP_RECEIVE_UDP_DATA

} BT_EventCodeEnum;


/**
  * @brief  event code enum definition
  */
typedef enum
{
    ENTER_HIBERNATE_MODE = 0,
    ENTER_LPM_MODE       = 1
} BT_MCU_SleepModeEnum;

/**
  * @brief  yichip HCI CMD Structure definition
  */

typedef struct
{
    uint8_t type;
    uint8_t opcode;
#if UART_EXT_ENABLE
    uint16_t DataLen;
#else
	uint8_t DataLen;
#endif
    uint8_t *p_data;
} HCI_TypeDef;

/**
  * @brief  yichip Btcode download Structure definition
  */

typedef struct
{
    uint16_t total_len;             /*patch总长度 = 所有的单包字节总长度之和*/
    uint16_t currentcalc_len;       /*当前传输总数据长度*/
    uint8_t  indexlen;              /*单包字节总长度=type+opcode+datapacketlen*/
    uint8_t  downfilestatus;        /*pacth下载完成状态*/
} BT_PatchTypedef;


typedef struct
{
    uint8_t *pBuf;
    int BufSize;
    int count;       /*!< count of valid data */
    int ReadIndex;
    int WriteIndex;
} BT_BufTypeDef;

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/


void _download_btcode(const byte *btcode);
G_Boolean BT_SetBtAddr(uint8_t *bt_addr);
G_Boolean BT_SetBleAddr(uint8_t *bt_addr);
G_Boolean BT_SetBtName(uint8_t *bt_name, uint16_t name_len);
G_Boolean BT_SetBleName(uint8_t *ble_name, uint16_t name_len);
G_Boolean BT_SetVisibility(uint8_t bt_discoverable, uint8_t bt_connectability, uint8_t ble_discoverable);
G_Boolean BT_SendSppData(uint8_t *spp_data, uint16_t len);
G_Boolean BT_SendBleData(uint8_t *ble_data, uint16_t len);
uint8_t Bt_GetBtStatus(void);
G_Boolean BT_SetParingMode(uint8_t mode);
G_Boolean BT_SetPincode(uint8_t *Pincode, uint8_t len);
uint32_t BT_GetVersion(void);
G_Boolean BT_BtDisconnect(void);
G_Boolean BT_SetNVRAM(uint8_t *NvData, int len);
G_Boolean BT_EnterSleepMode(void);
G_Boolean BT_SetLpmMode(uint8_t mode);
G_Boolean BT_ConfirmGkey(uint8_t isMatching);
G_Boolean BT_SetSppFlowcontrol(uint8_t packetNum);
G_Boolean BT_PasskeyEntry(uint8_t *key_data);
G_Boolean BT_SetLEParing(uint8_t mode);
G_Boolean BT_SetLEAdvData(uint8_t  *adv_data, int DataLen);
G_Boolean BT_SetLEScanData(uint8_t *scan_data, int DataLen);
G_Boolean BT_SetLESendConnUpdate(uint8_t *data, int len);
G_Boolean BT_SetLEAdvInterval(uint16_t ble_adv_interval);
G_Boolean BT_RejectJustWork(uint8_t justwork);
G_Boolean BT_Set_FixedPasskey(uint8_t *key);
G_Boolean BT_BleDisconnect(void);
G_Boolean BT_SetCOD(uint8_t *bt_cod);
G_Boolean BT_SetTxPower(uint8_t power);
G_Boolean BT_DeleteService(void);
G_Boolean BT_SetUartBaud(int baud);
G_Boolean BT_SetUartFlow(FunctionalState uartflow_ctrl);
uint16_t BT_AddBleService(uint8_t *ble_service_uuid, uint16_t service_uuid_len);
uint16_t BT_AddBleCharacteristic(uint8_t *ble_Characteristic_uuid, uint16_t service_Characteristic_payload_len);
int BT_ReadBTData(uint8_t *pbuf);
int BT_GetEventOpcode(void);
uint8_t BT_Init(void);
void BT_ParseBTData(void);
void Set_Soft_RTS_Enable_Rec(void);
void BT_Wakeup_Init(void);
void BT_Lpm_Wakeup_Init(void);
void Check_RecBT2M0Buf_Free(void);
G_Boolean BT_ReadBtRssi(void);
#define HCI_BTBLE_EVENTBUF_NUM 3
#define HCI_BTBLE_EVENTBUF_LEN 200

#define HCI_BTBLEDATA_BUF_NUM 10
#define HCI_BTBLEDATA_LEN 800

extern HCI_TypeDef hci_rec_btble_event[HCI_BTBLE_EVENTBUF_NUM];    //接收到btcode发送的需要保存数据的事件（除bt ble data event）
extern uint8_t hci_rec_btble_eventdata[HCI_BTBLE_EVENTBUF_NUM][HCI_BTBLE_EVENTBUF_LEN];
extern uint8_t hci_btbleeventbuf_write_index;
extern uint8_t hci_btbleeventbuf_read_index;

extern HCI_TypeDef hci_recappdata[HCI_BTBLEDATA_BUF_NUM];          //接收到btcode发送的bt ble data
extern uint8_t hci_btble_appdata[HCI_BTBLEDATA_BUF_NUM][HCI_BTBLEDATA_LEN];
extern uint8_t hci_appdatabuf_write_index;
extern uint8_t hci_appdatabuf_read_index;


#endif
